function Chess(opts) {
  opts = opts || {};
  // 棋盘尺寸
  this.chessSize = opts.chessSize || [4, 6];
  this._chessSize = [this.chessSize[0] + 2, this.chessSize[1] + 2];
  this._chessMap = [];
  this.sourceImage = opts.sourceImage;
  this.imageCouple = opts.imageCouple || 4;
  this.mode = opts.mode || 'single';
  // 空白棋盘
  this._blankPosition = [];
}
Chess.prototype = {
  constructor: 'Chess',
  initChess: function(){
    // 生成图片对
    var imageQueue=  this.createSource();
    // 生成棋盘
    this._chessMap = [];
    this._blankPosition = [];
    for (let i = 0; i < this._chessSize[0]; i += 1) {
      let arr = [];
      for(let j = 0; j < this._chessSize[1]; j += 1) {
        let type = 'normal';
        let backgroundImage = '';
        if(i === 0 || i === (this._chessSize[0] - 1) || j === 0 || j === (this._chessSize[1] - 1)) {
          type = 'blank';
          this._blankPosition.push([i, j]);
        } else {
          var index = Math.floor(Math.random() * imageQueue.length);
          backgroundImage = imageQueue[index];
          imageQueue.splice(index, 1)
        }
        arr.push({
          type: type,
          position: [i, j],
          className: [type],
          backgroundImage: backgroundImage,
        })
      }
      this._chessMap.push(arr);
    }
  },

  createSource: function() {
    var _image = [];
    var sourceTmp = this.sourceImage;
    for (var i = 0; i < this.imageCouple; i += 1){
      var index = Math.floor(Math.random() * sourceTmp.length);
      if(this.mode === 'couple') {
        // 生成偶数数列
        var even = createEven(this.imageCouple, sourceTmp.length);
        for (var i = 0; i < even.length; i += 1) {
          _image.push(sourceTmp[even[i]]);
          _image.push(sourceTmp[even[i] + 1]);
        }
      } else {
        _image.push(sourceTmp[index]);
        sourceTmp.splice(index, 1);
      }
    }

    var res = [];
    if(this.mode === 'couple') {
      for (var k = 0; k < this.chessSize[0] * this.chessSize[1]; k += 1) {
        var index = Math.floor(Math.random() * _image.length);
        res.push(_image[index]);
        _image.splice(index, 1);
      }
    } else {
      for (var k = 0; k < this.chessSize[0] * this.chessSize[1] / 2; k += 1) {
        var index = Math.floor(Math.random() * _image.length);
        res.push(_image[index]);
        res.push(_image[index]);
      }
    }

    return res;
  },

  isInBlank: function(position) {
    // 相邻时默认是在空白中的
    for (var i = 0; i < this._blankPosition.length; i += 1) {
      if(
        this._blankPosition[i][0] === position[0]
        && this._blankPosition[i][1] === position[1]
      ){
        return true;
      }
    }
    return false;
  },
  isOut: function(position) {
    return position[0] < 0
      || position[0] >= this._chessSize[0]
      || position[1] < 0
      || position[1] >= this._chessSize[1];
  },
  findSurround: function(position){
    return [
      [position[0] - 1, position[1]],
      [position[0] + 1, position[1]],
      [position[0], position[1] - 1],
      [position[0], position[1] + 1],
    ]
  },
  search: function(start, end) {
    // 初始化标记对象
    var marked = {}
    var tmp = this._blankPosition;
    tmp.push(start, end);
    for(var i = 0; i < tmp.length; i += 1){
      var key = 'k' + tmp[i][0] + tmp[i][1];
      marked[key] = {
        key: key,
        position: tmp[i],
        mark: false,
        edge: null
      }
    }

    var queue = [];
    queue.push('k' + start[0] + start[1]);
    watchDog = 1000;
    isFoundEnd = false;
    while (queue.length > 0 && watchDog > 0) {
      var qKey = queue.shift();
      var point = marked[qKey];
      if(!point.mark){
        /**
         * 该点没有被访问过，标注该点
         */
        if(
          point.position[0] === end[0]
          && point.position[1] === end[1]
        ) {
          // 访问点中出现终点
          isFoundEnd = true;
        }
        marked[qKey].mark = true;
        var sur = this.findSurround(point.position);
        let tmp = [];
        for (var index = 0; index < sur.length; index += 1) {
          // 记录访问的来源key
          var tmpKey = 'k' + sur[index][0] + sur[index][1];
          if(
            this.isInBlank(sur[index])
            && !this.isOut(sur[index])
            && !marked[tmpKey].mark
          ) {
            tmp.push(sur[index]);
            marked[tmpKey].edge = qKey;
            // 更新队列
            queue.push(tmpKey)
          }
        }
        if(tmp.length <= 0){
          // 没有周围的点，直接下一步
          continue;
        }
      }

      // 看门狗
      watchDog -= 1;
    }

    if(!isFoundEnd){
      // 没有查询到终点
      return false;
    }
    // 路径查找
    var path = [end];
    watchDog = 1000;
    while (
      path[path.length - 1][0] !== start[0]
      ||path[path.length - 1][1] !== start[1]
    ) {
      var tmpPoint = path[path.length - 1];
      var tmpKey = 'k' + tmpPoint[0] + tmpPoint[1];
      path.push(marked[marked[tmpKey].edge].position);
      watchDog --;
      if(watchDog < 0){
        break;
      }
    }
    return path;
  }

};


